/*
 * =====================================================================================
 *
 *       Filename:  cl_tcp_server.hxx
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  05/05/2011 03:51:02 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Ken Chen (Ken), chen_kenz@emc.com
 *        Company:  EMC
 *
 * =====================================================================================
 */

#ifndef _CL_TCP_SERVER_HXX_
#define _CL_TCP_SERVER_HXX_

#include <memory>
#include <atomic>
#include <vector>
#include <list>
#include "cl_channel.hxx"
#include "cl_socket_addr.hxx"
#include "cl_net_callback.hxx"
#include "cl_tcp_conn.hxx"

namespace neo
{
class CLEventLooper;
class CLServerSocket;
class CLTcpServer
{
public:
  CLTcpServer(const std::string& host, int port);
  ~CLTcpServer();
  void start(void);
  void setThreadNum(int numThreads);
  void setConnCallback(const CLConnCallback& cb);
  void setMessageCallback(const CLMessageCallback& cb);
  void setWriteCompleteCallback(const CLWriteCompleteCallback& cb);
  void setCloseCallback(const CLCloseCallback& cb);

private:
  void initIoLooper(void);
  void initFreeSlotTab(void);
	void init(void);
  void handleNewConnection(int sockfd, CLSocketAddrUPtr peerAddr);
  void recycleConnection(const CLTcpConnSPtr& conn);
  void recycleConnectionInLoop(const CLTcpConnSPtr& conn);
  int nextFreeSlot(void);
  CLEventLooper* nextIoLooper(void);

private:
  CLTcpServer(const CLTcpServer&);
  CLTcpServer& operator=(const CLTcpServer&);

private:
  // Event looper for handling client's connection request.
  std::unique_ptr<CLEventLooper> m_acceptLooper; 
  std::unique_ptr<CLServerSocket> m_acceptor;
  std::atomic<int> m_nextLooper;
  std::atomic<bool> m_started;
  // Event loopers for handling I/O
  int m_ioThrNum;
  std::vector<std::unique_ptr<CLEventLooper> > m_ioLoopers;
  typedef std::vector<CLTcpConnSPtr> ConnectionTab;
	typedef std::list<int> FreeSlotTab;
	ConnectionTab m_connections;
  FreeSlotTab m_freeSlots;

  CLConnCallback m_connCallback;
  CLMessageCallback m_msgCallback;
  CLWriteCompleteCallback m_writeCallback;
  CLCloseCallback m_closeCallback;
};

} // neo

#endif //_CL_TCP_SERVER_HXX_

